package com.winit.openapi.oauth.manager.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.fastjson.JSON;
import com.winit.common.orm.mybatis.PageBase;
import com.winit.common.query.Page;
import com.winit.common.query.SearchOperator;
import com.winit.common.query.Searchable;
import com.winit.common.query.Sort;
import com.winit.common.query.Sort.Direction;
import com.winit.common.query.filter.SearchFilterHelper;
import com.winit.common.spi.SPIException;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.exception.ApiBizException;
import com.winit.openapi.oauth.command.QueryUserAuthInfoByClientCommand;
import com.winit.openapi.oauth.command.QueryUserAuthInfoByUserCommand;
import com.winit.openapi.oauth.dao.APIClientDao;
import com.winit.openapi.oauth.dao.UserAuthorizationDao;
import com.winit.openapi.oauth.entity.APIClientEntity;
import com.winit.openapi.oauth.entity.UserAuthorizationEntity;
import com.winit.openapi.oauth.manager.UserAuthorizationManager;
import com.winit.openapi.oauth.vo.UserAuthorizationVo;
import com.winit.openapi.util.BeanUtils;
import com.winit.ums.spi.UmsCustomerService;
import com.winit.ums.spi.commnad.customer.QueryCompanylCommand;
import com.winit.ums.spi.vo.CustomerInfoVO;

@Service("userAuthorizationManager")
public class UserAuthorizationManagerImpl implements UserAuthorizationManager {

    private Logger               logger = LoggerFactory.getLogger(UserAuthorizationManagerImpl.class);

    @Resource
    private UserAuthorizationDao userAuthorizationDao;
    @Resource
    private UmsCustomerService   umsCustomerService;
    @Resource
    private APIClientDao         apiClientDao;

    @Override
    @Transactional
    public void insertOrUpdate(UserAuthorizationVo vo) {
        QueryCompanylCommand command = new QueryCompanylCommand();
        command.setEmail(vo.getUserName());
        try {
            CustomerInfoVO companyVo = umsCustomerService.queryCompanyByUserName(command);
            if (null != companyVo) {
                vo.setCompanyName(companyVo.getName());
            }
            UserAuthorizationEntity entity = userAuthorizationDao.queryByClientAndUser(vo.getClientId(), vo.getUserId());
            synUserInfo(vo);
            // 说明是新添加
            if (entity == null) {
                userAuthorizationDao.insertSelective(BeanUtils.copyProperties(vo, UserAuthorizationEntity.class));
                logger.info("API OAuth2.0用户进行授权操作：" + JSON.toJSONString(vo));
                return;
            }
            vo.setId(entity.getId());
            vo.setUpdated(new Date());
            vo.setUpdatedby(entity.getUpdatedby() == null ? entity.getCreatedby() : entity.getUpdatedby());
            // 复制属性
            BeanUtils.copyProperties(vo, entity);
            userAuthorizationDao.updateSelective(entity);
            logger.info("API OAuth2.0用户进行更新授权操作：更新前授权信息：" + JSON.toJSONString(entity) + " 更新后授权信息："
                        + JSON.toJSONString(vo));
        } catch (SPIException e) {
            logger.error("用户授权异常,error:{}", e);
            throw new ApiBizException(ErrorCode.OAUTH_CREATE_USER_AUTH_ERROR);
        }
    }

    @Override
    public List<UserAuthorizationVo> queryByClientId(Long clientId) {
        List<UserAuthorizationEntity> userList = new ArrayList<UserAuthorizationEntity>();
        try {
            userList = userAuthorizationDao.queryByClientId(clientId);
        } catch (SPIException e) {
            logger.error("查询用户授权信息异常,error:{}", e);
            throw new ApiBizException(ErrorCode.OAUTH_QUERY_USER_AUTH_ERROR);
        }
        BeanUtils.copyList(userList, UserAuthorizationVo.class);
        return BeanUtils.copyList(userList, UserAuthorizationVo.class);
    }

    @Override
    public int getUserCountByClient(Long clientId) {

        return userAuthorizationDao.getUserCountByClient(clientId);
    }

    private void synUserInfo(UserAuthorizationVo vo) {

        String userName = vo.getUserName();

        String companyName = vo.getCompanyName();

        if (StringUtils.isNotBlank(userName) && StringUtils.isNotBlank(companyName)) {
            try {
                userAuthorizationDao.synUserInfo(vo.getUserId(), userName, companyName);
            } catch (Exception e) {
                logger.error("用户授权异常,error:{}", e);
                throw new ApiBizException(ErrorCode.OAUTH_CREATE_USER_AUTH_ERROR);
            }
        }

    }

    @Override
    public void unbind(Long clientId, Long userId) {
        try {
            UserAuthorizationEntity entity = userAuthorizationDao.queryByClientAndUser(clientId, userId);
            if (null == entity) {
                return;
            }
            entity.setIsActive("N");
            // entity.setIsDelete("Y");
            entity.setUpdated(new Date());
            entity.setUpdatedby(entity.getUserName());
            userAuthorizationDao.updateSelective(entity);
            logger.info("API OAuth2.0用户进行授权解除操作,操作者：" + entity.getUserName() + " 被解除的应用：" + entity.getClientName());
        } catch (Exception e) {
            logger.error("解除用户授权异常,error:{}", e);
            throw new ApiBizException(ErrorCode.OAUTH_DISABLE_USER_AUTH_ERROR);
        }

    }

    @Override
    public UserAuthorizationVo queryByClientAndUser(Long clientId, Long userId) {
        UserAuthorizationEntity entity = null;
        try {
            entity = userAuthorizationDao.queryByClientAndUser(clientId, userId);
            if (null == entity) {
                return null;
            }
        } catch (Exception e) {
            logger.error("查询用户授权信息异常,error:{}", e);
            throw new ApiBizException(ErrorCode.OAUTH_QUERY_USER_AUTH_ERROR);
        }
        return BeanUtils.copyProperties(entity, UserAuthorizationVo.class);
    }

    @Override
    public Page<UserAuthorizationVo> findPageByClientId(QueryUserAuthInfoByClientCommand command) {
        Searchable searchable = command.getSearchable();
        if (CollectionUtils.isNotEmpty(command.getClientIdList())) {
            String clientIdString = genClientIdSqlString(command.getClientIdList());
            searchable.addSearchFilter(SearchFilterHelper.newCondition("CLIENT_ID", SearchOperator.in, "("
                                                                                                       + clientIdString
                                                                                                       + ")"));
        }
        searchable.addSearchFilter(SearchFilterHelper.newCondition("IS_DELETE", SearchOperator.eq, "N"));
        searchable.addSearchFilter(SearchFilterHelper.newCondition("IS_ACTIVE", SearchOperator.eq, "Y"));
        searchable.addSort(new Sort(Direction.DESC, "CREATED"));

        PageBase<UserAuthorizationEntity> pageBase = userAuthorizationDao.find(searchable);
        if (null == pageBase) {
            return null;
        }
        return BeanUtils.copyPageList(pageBase, UserAuthorizationVo.class);

    }

    @Override
    public Page<UserAuthorizationVo> findPageByUserId(QueryUserAuthInfoByUserCommand command) {
        Searchable searchable = command.getSearchable();
        if (command.getUserId() != null) {
            searchable.addSearchFilter(SearchFilterHelper.newCondition("USER_ID",
                SearchOperator.eq,
                command.getUserId()));
        }
        searchable.addSearchFilter(SearchFilterHelper.newCondition("IS_DELETE", SearchOperator.eq, "N"));
        // 失效的也要显示
        // searchable.addSearchFilter(SearchFilterHelper.newCondition("IS_ACTIVE",
        // SearchOperator.eq, "Y"));
        searchable.addSort(new Sort(Direction.DESC, "IS_ACTIVE", "CREATED"));

        PageBase<UserAuthorizationEntity> pageBase = userAuthorizationDao.find(searchable);
        if (null == pageBase) {
            return null;
        }

        return BeanUtils.copyPageList(pageBase, UserAuthorizationVo.class);
    }

    /**
     * 根据名称，邮箱，手机号 模糊查询
     * 
     * @param entity
     * @return
     */
    private String genClientIdSqlString(List<Long> ids) {
        StringBuffer clientIdString = new StringBuffer("");
        if (CollectionUtils.isNotEmpty(ids)) {
            for (Long id : ids) {
                clientIdString.append(id).append(",");
            }
            if (StringUtils.isNotBlank(clientIdString)) {
                clientIdString = new StringBuffer(clientIdString.substring(0, clientIdString.length() - 1));
                return clientIdString.toString();
            } else {
                return null;
            }
        } else {
            return null;
        }
    }

    @Override
    public UserAuthorizationVo queryByClientAndUserName(Long clientId, String userName) {
        UserAuthorizationEntity entity = null;
        try {
            entity = userAuthorizationDao.queryByClientAndUserName(clientId, userName);
            if (null == entity) {
                return null;
            }
        } catch (Exception e) {
            logger.error("查询用户授权信息异常,error:{}", e);
            throw new ApiBizException(ErrorCode.OAUTH_QUERY_USER_AUTH_ERROR);
        }
        return BeanUtils.copyProperties(entity, UserAuthorizationVo.class);
    }

    @Override
    public UserAuthorizationVo queryByClientKeyAndUserName(String clientKey, String userName) {
        try {
            APIClientEntity clientEntity = apiClientDao.selectByClientKey(clientKey);
            if (clientEntity == null) {
                return null;
            }
            return queryByClientAndUserName(clientEntity.getId(), userName);
        } catch (Exception e) {
            logger.error("查询用户授权信息异常,error:{}", e);
            throw new ApiBizException(ErrorCode.OAUTH_QUERY_USER_AUTH_ERROR);
        }
    }
}
